const express = require('express')
const cookieParser = require('cookie-parser')

let server = express()

server.use('/home',(req,res) => {
    res.cookie('user','item',{path:'/home',maxAge:3600*24*10})  //给访问者种一条普通cookie
    res.send('ok')
})

server.listen(8888,() => {
    console.log('the server running at 8888端口')
})


/**
 * 
 * cookie分为如下几步实现：
1. 服务器端向客户端发送cookie。
2. 浏览器将cookie保存。
3. 之后每次请求都会将cookie发向服务器端。

1.1 服务器端发送cookie
    服务器发送cookie给客户端是通过HTTP响应报文实现的。在set-Cookie中设置给客户端发送的cookie，cookie格式如下：
Set-Cookie: name=value; Max-Age=60; Path=/; domain=.domain.com;Expires=Sun, 27 May 2018 05:44:24 GMT; HttpOnly, secure;

name: 一个唯一确定cookie的名称。
value： 存储在cookie中字符串的值。
domain: cookie对于那个域下是有效的，
path: 表示这个cookie影响到的路径，浏览器会根据这个配置，向指定的域中匹配的路径发送cookie。
expires: 失效时间，表示cookie何时失效的时间，如果不设置这个时间，浏览器就会在页面关闭时将删除所有的cookie，
max-age: 用来告诉浏览器此cookie多久过期(单位是秒)，一般的情况下，max-age的优先级高于expires。
HttpOnly: 告诉浏览器不允许通过脚本document.cookie去更改值，这个值在document.cookie中也是不可见的，但是在http请求会携带这个cookie，

secure：安全标志，指定后，当secure为true时候，在HTTP中是无效的，在HTTPS中才有效，表示创建的cookie只能在HTTPS连接中
被浏览器传递到服务器端进行会话验证，如果是HTTP连接则不会传递该信息，所以一般不会被且听到。


服务器端设置cookie代码如下：

const express = require('express');
const app = express();

app.listen(3001, () => {
  console.log('port listen 3001');
});

app.get('/', (req, res) => {
  res.setHeader('status', '200 OK');
  res.setHeader('Set-Cookie', 'isVisit=1;domain=/;path=/;max-age=60*1000');
  res.send('欢迎你~');
});

直接设置Set-Cookie过于原始，我们可以对cookie的设置过程做如下封装；

const express = require('express');
const app = express();

app.listen(3001, () => {
  console.log('port listen 3001');
});

const serilize = function(name, value, options) {
  if (!name) {
    throw new Errpr('cookie must have name');
  }
  var rets = [];
  value = (value !== null && value !== undefined) ? value.toString() : '';
  options = options || {};
  rets.push(encodeURIComponent(name) + "=" +encodeURIComponent(value));
  if (options.domain) {
    rets.push('domain=' + options.domain);
  }
  if (options.path) {
    rets.push('path=' + options.path);
  }
  if (options.expires) {
    rets.push('expires=' + options.expires.toGMTString());
  }
  if (options.maxAge && typeof options.maxAge === 'number') {
    rets.push('max-age=' + options.maxAge);
  }
  if (options.httpOnly) {
    rets.push('HTTPOnly');
  }
  if (options.secure) {
    rets.push('secure');
  }
  return rets.join(';');
};

app.get('/', (req, res) => {
  res.setHeader('status', '200 OK');
  res.setHeader('Set-Cookie', serilize('isVisit', '1'));
  res.send('欢迎你~');
});

服务器端解析代码如下：
1.3 express中的cookie

const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();

app.listen(3000, () => {
  console.log('port listen 3000');
});

app.use(cookieParser());

app.get('/', (req, res) => {
  if (req.cookies.isVisit) {
    console.log(req.cookies);
    res.send('再次欢迎你');
  } else {
    // cookie设置过期时间为10分钟
    res.cookie('isVisit', 1, {maxAge: 60*1000});
    res.send('欢迎你~');
  }
});

express 中 express-session模块

在express中操作session可以使用 express-session这个模块，主要方法是session(options),options中包含可选的参数有：
name: 保存session的字段名称。默认为 connect.sid
store: session的存储方式，默认存放在内存中。
secret： 通过设置secret字符串，来计算hash值并放在cookie中，使产生的signedCookie防篡改。
cookie： 设置存放session id的cookie的相关选项，默认为 (default: { path: '/', httpOnly: true, secure: false, maxAge: null })
genid: 产生一个新的 session_id 时，所使用的函数， 默认使用 uid2 这个 npm 包。
rolling: 每个请求都重新设置一个 cookie，默认为 false。
resave: 即使 session 没有被修改，也保存 session 值，默认为 true

2.2 在内存中存储session

const express = require('express');
const session = require('express-session');
const app = express();
app.listen(3002, () => {
  console.log('port listen 3002');
});
app.use(session({
  secret: 'somesecrettoken',
  cookie: { maxAge: 1*60*1000 }  // 1分钟
}));
app.get('/', (req, res) => {
 
  // 检查session中的isVisit字段

 if (req.session.isVisit) {
    res.send('再次欢迎你');
  } else {
    req.session.isVisit = true;
    res.send('欢迎你第一次来~');
  }
});


 * 
 */